﻿if exists (select 1
          from sysobjects
          where  id = object_id('bd_proc_import_leave')
          and type in ('P','PC'))
   drop procedure bd_proc_import_leave
go


create PROCEDURE bd_proc_import_leave
  @serialNumber AS varchar(20) ,
  @operator AS varchar(20)
AS
BEGIN
	--名称：导入请假保存
	--思路：
			--1、从bd_temp_import_leave表中取出对应的数据
			--2、游标遍历每条记录(根据bd_proc_sys_getMaxNumber 获取order_no，bd_proc_sys_getMaxId获取order_Id， classId = 5）
				--2.1、根据bd_temp_import_leave和人员表（dt_user）来判断该人员是否存在（以user_no关联），
				--不存在的人员将bd_temp_import_leave表中的该条信息放入失败信息表中。定义错误类型：人员信息不存在。进入下一个循环。
				--2.2、根据bd_temp_import_leave与假类表（kt_qingj）来判断假类是否存在（以leave_name关联），
				--不存在的假类则将bd_temp_import_leave表中的该条信息放入失败信息表中。定义错误类型：假类不存在。进入下一个循环。
				--2.3、生成请假日期数据（临时表，带人员信息和每日请假时长分钟数）,
				--2.4、根据临时表和请假明细单（lr_kqingj）来判断请假记录是否有重复（同种假类，每天只能出现一次），
				--若有重复则将bd_temp_import_leave表中的该条信息放入失败信息表中。定义错误类型：同天不能多次申请同种假类。进入下一个循环。
				--2.5、以上几点都正常，则根据bd_temp_import_leave 生产请假单，根据临时表生成请假明细单。

	DECLARE @dept_name varchar(50)    --部门名称
  DECLARE @offices_name varchar(50) -- 科室名称
  DECLARE @by_company varchar(50)   --所属公司名称
  DECLARE @user_no varchar(50)      --工号
  DECLARE @user_name varchar(50) 		--姓名
  DECLARE @leave_name varchar(50) 	--假类名称
  DECLARE @begin_date date 					--开始日期
  DECLARE @end_date date 						--结束日期
  DECLARE @begin_time varchar(50) 	--开始时间mm:ss
  DECLARE @end_time varchar(50) 		--结束时间mm:ss
  DECLARE @leave_hours decimal 			--请假总时长小时数
  DECLARE @remark varchar(max) 			--备注



	DECLARE @counts int = 0 --判断返回条数，公共。
	DECLARE @counts2 int = 0 --判断返回条数，公共。
	DECLARE @flag int = 0 --boolean。


	DECLARE @days int --请假天数（针对一条记录而言，用于计算每日请假分钟数）
	DECLARE @leave_minute int --每日请假分钟数（平均值）

	DECLARE @leave_id varchar(10)	--假类ID
	DECLARE @user_serial bigint --人员ID

	DECLARE @order_id int --请假单ID
	DECLARE @order_no varchar(20) --请假单编号

	declare @sql varchar(max) = '' --动态sql

	--请假明细临时表
	create table #temp_data(
		user_serial bigint,--人员ID
		leave_id varchar(10),--假类ID
		leave_date date,--请假日期
		leave_minute INT, --请假时长分钟数
    settle_year INT,
    settle_month  INT,
    settle_date DATE
	)

	--错误信息
	create table #return_data(
		dept_name varchar(50) COLLATE Chinese_PRC_CI_AS,
		offices_name varchar(50) COLLATE Chinese_PRC_CI_AS,
		by_company varchar(50) COLLATE Chinese_PRC_CI_AS,
		user_no varchar(50) COLLATE Chinese_PRC_CI_AS,
		user_name varchar(50) COLLATE Chinese_PRC_CI_AS,
		leave_name varchar(50) COLLATE Chinese_PRC_CI_AS,
		begin_date varchar(50),
		end_date varchar(50),
		begin_time varchar(50),
		end_time varchar(50),
		leave_hours DECIMAL,
		error_msg varchar(2000) COLLATE Chinese_PRC_CI_AS
	)

	--遍历调用
	DECLARE leaveList CURSOR LOCAL FOR
	SELECT
				dept_name,
				offices_name,
				by_company,
				user_no,
				user_name,
				leave_name,
				begin_date,
				end_date,
				begin_time,
				end_time,
				leave_hours,
				remark
	FROM bd_temp_import_leave
	where serial_number = @serialNumber;

	OPEN leaveList
	FETCH NEXT FROM leaveList INTO @dept_name, @offices_name,@by_company,@user_no,@user_name,
	@leave_name,@begin_date,@end_date,@begin_time,@end_time,@leave_hours,@remark

	WHILE @@fetch_status = 0
		BEGIN
				set @counts = 0;
				set @counts2 = 0;
				set @user_serial = 0;
				set @leave_id = '';
				set @flag = 0;
				TRUNCATE TABLE #temp_data

				--1.判断该人员是否存在
				select @user_serial = user_serial from dt_user where user_no = @user_no
				if @user_serial != 0
					BEGIN

						--2.判断假类是否存在
						select @leave_id = bh from kt_qingj where mc = @leave_name;
						if @leave_id != ''
							BEGIN
								--请假明细临时表
								--根据@begin_date、@end_date 分解到每天。
								SET @days = DATEDIFF(DAY, @begin_date, @end_date)+1;
								set @leave_minute = @leave_hours*60/@days;

								--插入明细数据
								insert into #temp_data (user_serial, leave_id, leave_date, leave_minute)
								select @user_serial,@leave_id,DATEADD(dd, number, @begin_date),@leave_minute
								from master.dbo.spt_values
								where type = 'p' and number <=DATEDIFF(DAY, @begin_date,@end_date)

								--判断同天是否有存在的假
								select @counts = count(1) from lr_kqingj k INNER JOIN #temp_data d on k.user_serial = d.user_serial and convert(varchar(10),k.kssj,120) = convert(varchar(10),d.leave_date,120) and k.bh = d.leave_id and k.whether_validity = 1;

								if @counts = 0
									BEGIN
										--处理不排班就不能申请（目前仅仅有放班）

										if @leave_id = '00113'
											BEGIN
												--请假日期内，只要有一天未排班，该人员就不能申请请假。
												select @counts = count(1) from (select shift_date
														from bd_kq_schedule_detail
														where user_serial = @user_serial
														and convert(varchar(10),shift_date,120) in (
															select convert(varchar(10),leave_date,120) from #temp_data
														)
														GROUP BY shift_date
														) a
												--本次请假天数
												select @counts2 = count(1) from #temp_data;
												--本次请假天数若大于这几天排班的天数，说明存在某日期未排班。
												if @counts2>@counts
													BEGIN
														set @flag = 1;
													END
											END

										if @flag = 0
											BEGIN
												--生成单号和ID
												exec bd_proc_sys_getMaxNumber '5',@order_no output
												exec bd_proc_sys_getMaxId 5,@order_id output
												--保存请假单
												insert into bd_leave_order (
														order_id,
														order_no,
														leave_id,
														start_date,
														end_date,
														people_num,
														total_time,
														remark,
														creater_id,
														apply_type,
														status,
														begin_time,
														end_time
												)VALUES(
														@order_id,
														@order_no,
														@leave_id,
														@begin_date,
														@end_date,
														1,
														@leave_hours*60,
														@remark,
														@operator,
														2,
														4,
														@begin_time,
														@end_time
												);

                        UPDATE #temp_data SET settle_date = dbo.bd_fn_getSettleDate(leave_date)
                        UPDATE #temp_data SET settle_year = YEAR(settle_date), settle_month = MONTH(settle_date)

												--保存请假明细单
												insert into lr_kqingj(
													user_serial,
													bh,
													kssj,
													jssj,
													jsjg,
													gly_no,
													order_id,
                          settle_year, 
                          settle_month,
                          whether_validity
												)
												select
													user_serial,
													leave_id,
													leave_date,
													leave_date,
													leave_minute,
													@operator,
													@order_id,
                          ISNULL(settle_year, 0), 
                          ISNULL(settle_month, 0),
                          1
												from #temp_data

												--针对请假类型为放班的需要处理排班状态为[F]
												if @leave_id = '10003'
													BEGIN
														--更新kt_paiba 中的排班状态符号
														select @sql += concat('update kt_paiba set d',datepart(dd,leave_date),' =
														'''+'[F]'+'''+ SUBSTRING(d',datepart(dd,leave_date),',4,len(d',datepart(dd,leave_date),')),
														gly_no = ''',@operator,''' where user_serial = ''',user_serial,''' and rq = ''',
														convert(varchar(7),leave_date,120),'''; ')
														from #temp_data

														-- 执行更新排班表
														exec(@sql);

														--更新排班明细表
														update d
															set d.shift_name = '[F]'+SUBSTRING(d.shift_name, 4, len(d.shift_name)),
																	d.shift_is_rest = 2
															from bd_kq_schedule_detail d
															INNER JOIN  #temp_data t on d.user_serial = t.user_serial
																and convert(varchar(10),t.leave_date,120) = convert(varchar(10),d.shift_date,120)

													END
											END
										else
											BEGIN
												--请假类型为放班  且存日期没有排班
												insert  into #return_data values(@dept_name, @offices_name,@by_company,@user_no,@user_name,
												@leave_name,@begin_date,@end_date,@begin_time,@end_time,@leave_hours,'放班，对应日期存在未排班')
											END
									END
								ELSE
									BEGIN
										--存在同假
										insert  into #return_data values(@dept_name, @offices_name,@by_company,@user_no,@user_name,
										@leave_name,@begin_date,@end_date,@begin_time,@end_time,@leave_hours,'同天不能多次申请同种假类')
									END
							END
						else
							BEGIN
								--假类不存在
								insert  into #return_data values(@dept_name, @offices_name,@by_company,@user_no,@user_name,
								@leave_name,@begin_date,@end_date,@begin_time,@end_time,@leave_hours,'假类信息不存在')
							END
					END
				else
					BEGIN
					--人员不存在
						insert  into #return_data values(@dept_name, @offices_name,@by_company,@user_no,@user_name,
						@leave_name,@begin_date,@end_date,@begin_time,@end_time,@leave_hours,'人员信息不存在')
					END
			FETCH NEXT FROM leaveList INTO @dept_name, @offices_name,@by_company,@user_no,@user_name,@leave_name,
			@begin_date,@end_date,@begin_time,@end_time,@leave_hours,@remark
		END

	CLOSE leaveList
	select * from #return_data
END
go

